//options:外部传入的配置项(el data....)
function MVVM(options) {
    //this: vm实例对象
    this.$options = options;
    var data = this._data = this.$options.data;
    var me = this;

    //实现数据代理!
    //Object.keys(data) : 拿到data所有可枚举属性组成的数组
    Object.keys(data).forEach(function(key) {
        //key:data中的一个个可枚举属性的名称
        me._proxy(key);
    });

    //实现数据劫持!
    observe(data, this);

    //模板解析
    this.$compile = new Compile(options.el || document.body, this)
}

MVVM.prototype = {
    $watch: function(key, cb, options) {
        new Watcher(this, key, cb);
    },

    //实现了数据转绑(数据代理)
    //key:data中的一个个可枚举属性的名称
    _proxy: function(key) {
        var me = this; //都是vm实例对象

        //Object.defineProperty : 给对象新增或修改属性!!!
        Object.defineProperty(me, key, {
            configurable: false,
            enumerable: true,
            get: function proxyGetter() {
                return me._data[key];
            },
            set: function proxySetter(newVal) {
                me._data[key] = newVal;
            }
        });
    }
};